package infra

import (
	log "github.com/sirupsen/logrus"
	"github.com/tietang/props/kvs"
	"reflect"
)

const (
	KeyProps = "_conf"
)

//应用程序
type BootApplication struct {
	conf         kvs.ConfigSource
	startContext StarterContext
}

func New(conf kvs.ConfigSource) *BootApplication {
	b := &BootApplication{conf: conf, startContext: StarterContext{}}
	b.startContext[KeyProps] = conf
	return b
}

func (b *BootApplication) init() {
	log.Info("Initializing starters...")
	for _, v := range GetStarters() {
		typ := reflect.TypeOf(v)
		log.Debugf("Initializing: PriorityGroup=%d,Priority=%d,type=%s", v.PriorityGroup(), v.Priority(), typ.String())
		v.Init(b.startContext)
	}
}

func (b *BootApplication) setup() {
	log.Info("Setup starters...")
	for _, v := range StarterRegister.AllStarters() {
		typ := reflect.TypeOf(v)
		log.Debug("Setup: ", typ.String())
		v.Setup(b.startContext)
	}
}

func (b *BootApplication) start() {
	for i, starter := range StarterRegister.AllStarters() {
		if starter.StartBlocking() {
			if i+1 == len(StarterRegister.AllStarters()) {
				starter.Start(b.startContext)
			} else {
				go starter.Start(b.startContext)
			}
		} else {
			starter.Start(b.startContext)
		}
	}
}

func (b *BootApplication) Start() {
	b.init()

	b.setup()

	b.start()
}
